home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume90
/
util
/
bsindex1
/
part01
/
src
/
checkfiles.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-02-02
|
7KB
|
257 lines
/*
* CHECKFILES.C
*
* This module contains routines to read in the disk directory, search
* the file database for each filename found to see if it matches, etc.
*
*/
#ifndef LATTICE_50
#include "system.h"
#endif
#include "bbsindex.h"
/*
* addunknown()
* ------------
* Adds a new entry to the list of unknown files found. If necessary,
* more memory will be allocated to hold the new entry.
*/
int addunknown(name, size, date, dirnum)
char *name;
long size;
int date, dirnum;
{
static DIRENTRY *dirbase, *dir;
if (numdirentries >= MAXDIRENT) {
scripterror("directory table full. Skipping rest of files\n");
return (FALSE);
}
if ((numdirentries % DIRFRAG) == 0) /* Allocate new block */
dirbase = mymalloc(DIRENTRYSIZE * DIRFRAG);
dir = &dirbase[numdirentries % DIRFRAG];
strcpy(dir->name, name);
dir->size = size;
dir->date = date;
dir->dirnum = dirnum;
direntries[numdirentries++] = dir;
return (TRUE);
}
/*
* find()
* ------
* Does a binary search of the file records looking for the specified
* filename. Returns pointer to the file record if found, NULL if not
* found.
*/
UDHEAD *find(name)
char *name;
{
long low = 0, high = numrecs -1;
long mid;
int cmp;
while (high >= low) {
mid = (low + high) / 2;
cmp = stricmp(ptrblock[mid]->disk_name, name);
if (!cmp && ptrblock[mid]->type == 0) /* Found match */
return (ptrblock[mid]);
if (cmp > 0) /* Too far ahead, go backwards */
high = mid-1;
else /* Too far below, go forwards */
low = mid+1;
}
return (NULL);
}
/*
* scandir()
* ---------
* Scans directory, adding the files found either to the 'unknown'
* list or updating the pointers in the main file database appropriately.
*/
int scandir(dirname, dirnum)
char *dirname;
int dirnum;
{
UDHEAD *f;
struct tm *filedate;
int bbspcdate;
dirlock = Lock(dirname, ACCESS_READ);
if (dirlock == NULL) {
scripterror("can't find directory ");
print2(dirname, ", skipping\n");
return (TRUE);
}
if (!Examine(dirlock, fib)) {
scripterror("can't examine directory ");
print2(dirname, ", skipping\n");
UnLock(dirlock);
dirlock = NULL;
return (TRUE);
}
while (ExNext(dirlock, fib)) {
chkabort();
if (fib->fib_DirEntryType > 0) /* Skip over directories */
continue;
if (f = find(fib->fib_FileName)) {
f->online = 1;
f->valid = (fib->fib_Size == f->length);
f->dirnum = dirnum;
} else {
/*
* Convert AmigaDOS date (# days since 1/1/78, # mins
* since midnight) into ANSI date (# seconds since 1/1/70)
* then convert that into BBS-PC! format.
*/
long ansidate;
ansidate = (fib->fib_Date.ds_Days + (365 * 8) + 2) * 86400;
filedate = gmtime(&ansidate);
bbspcdate = (((filedate->tm_year * 13) +
(filedate->tm_mon+1)) * 32) +
filedate->tm_mday;
if (!addunknown(fib->fib_FileName, fib->fib_Size, bbspcdate,
dirnum)) {
UnLock(dirlock);
dirlock = NULL;
return (FALSE);
}
}
}
if (IoErr() != ERROR_NO_MORE_ENTRIES) {
scripterror("error reading directory ");
print2(dirname, ", skipping\n");
}
UnLock(dirlock);
dirlock = NULL;
return (TRUE);
}
/*
* diskcmp()
* ---------
* Compares the disk filenames of two file headers, and returns true
* if they are equal. Used by the sort routine in check_files().
*/
int diskcmp(f1,f2)
UDHEAD **f1, **f2;
{
return (stricmp((*f1)->disk_name, (*f2)->disk_name));
}
/*
* com_checkfiles()
* ----------------
* This command scans the file directories specified on the command
* line (or if none, then using those specified in the CFGINFO.DAT
* file). Each file in the catalogue is searched for in the file
* catalogue, and those that are found are marked as "Online"; if
* the disk filesize matches the catalogue filesize, then their
* "valid" flag is also set. Files which are not found are stored
* in a seperate array, which can be printed with the FOREIGN command.
* After this, any other files listed in the IGNORE list are also marked
* as valid.
*
* Note that before the scan, the files are sorted into alphabetical
* order, by diskname, to allow a binary search to be done. Afterwards,
* if this disrupted a previous sorting order, they are sorted back
* to their original state.
*/
void com_checkfiles()
{
int dirnum;
IGNORE *ig;
UDHEAD *f;
if (checkfiles)
return;
CHECKDATABASE();
qsort(ptrblock, numrecs, sizeof(UDHEAD *), diskcmp);
if (compos >= comlen) {
readconfigfile();
for (dirnum = 0; dirnum < NUM_SECT && dirnames[dirnum][0]; dirnum++) {
chkabort();
if (!scandir(dirnames[dirnum], dirnum))
break;
}
} else {
for (dirnum = 0; dirnum < NUM_SECT; dirnum++) {
if (compos >= comlen)
break;
strcpy(dirnames[dirnum], getstring());
chkabort();
if (!scandir(dirnames[dirnum], dirnum))
break;
}
}
/*
* Now mark any "ignored" files as valid.
*/
for (ig = firstignore; ig; ig = ig->next) {
if (f = find(ig->name))
f->valid = 1;
}
chkabort();
if (sorted)
qsort(ptrblock, numrecs, sizeof(UDHEAD *), sortcmp);
checkfiles = TRUE;
}
/*
* com_foreign()
* -------------
* This command prints out the list of foreign files, i.e. files
* not in the catalogue, using the format string setup with
* FORMAT. Not all fields are valid.
*/
void com_foreign()
{
/*
* Standard file header template for foreign files.
* Note file[] is an array, so we can say file->x instead of file.x
*/
static UDHEAD file[1] = {{
0, /* Record type (== valid) */
1, 1, 1, 1, /* Local, Binary, Valid and Online :-) */
0, /* Directory number is set later */
"", /* Catalogue filename, filled in later */
0, /* Date is set later */
0, 0, 0, /* Section 0, Directory 0, no accesses */
0, /* Length is set later */
"", /* Disk name is set later */
"AmigaDos", /* The file owner */
"Directory = ", /* File comment, set later */
}};
int i;
if (!checkfiles) {
scripterror("can't do FOREIGN before CHECKFILES\n");
Cleanup(10);
}
for (i = 0; i < numdirentries; i++) {
chkabort();
/* Setup actual file parameters for format() */
strcpy(file->disk_name, direntries[i]->name);
strncpy(file->cat_name, direntries[i]->name, CAT_LEN);
strncpy(file->desc+12, dirnames[direntries[i]->dirnum], DESC_LEN-12);
file->desc[DESC_LEN] = CHAR_NULL;
file->length = direntries[i]->size;
file->date = direntries[i]->date;
file->dirnum = direntries[i]->dirnum;
format(out, MAXOUT, formatstring, file, checkfiles);
putstring(out);
}
}